home
diamond Go Premium
Data Engineering Path  ·  PySpark

SQL Joins

Joining datasets is one of the most fundamental operations in relational data processing. Spark DataFrames support all standard SQL join types, as well as highly optimized streaming-oriented joins.

graph TD
    subgraph StandardJoins["Standard Relational Joins"]
        direction LR
        J1["Inner Join<br>(Matches on both)"]
        J2["Outer Joins<br>(Matches + Null padded mismatches)"]
    end
    subgraph FilteringJoins["Filtering Joins (No Right Table Columns)"]
        direction LR
        J3["Left Semi Join<br>(Returns matching left records)"]
        J4["Left Anti Join<br>(Returns mismatched left records)"]
    end
    style StandardJoins fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
    style FilteringJoins fill:#faf5ff,stroke:#9333ea,stroke-width:2px;

Join Types Supported in Spark

To execute a join, call the join() method on your left DataFrame: left_df.join(right_df, on_expression, join_type)

Join Type (how) Description Example
"inner" Returns rows where keys match in both DataFrames (Default). left.join(right, "id", "inner")
"left" / "left_outer" Returns all rows from the left, plus matching rows from the right (fills with null if no match). left.join(right, "id", "left")
"right" / "right_outer" Returns all rows from the right, plus matching rows from the left. left.join(right, "id", "right")
"full" / "full_outer" Returns all rows from both sides (joins where keys match, fills with null where mismatched). left.join(right, "id", "full")
"left_semi" Filtering Join: Returns rows from the left table that have matching keys in the right table. Columns from the right table are completely omitted! left.join(right, "id", "left_semi")
"left_anti" Filtering Join: Returns rows from the left table that *do not* have matching keys in the right table. Excellent for finding orphaned keys! left.join(right, "id", "left_anti")

PySpark Code Example: Executing Standard and Advanced Joins

Here is a complete, copy-paste-ready script showing how to perform joins using single keys, multiple keys, and advanced Semi/Anti joins:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col

# 1. Setup Spark
spark = SparkSession.builder \
    .appName("SQL Joins") \
    .master("local[*]") \
    .getOrCreate()

# 2. Sample Datasets
# Left: Employees
employees_data = [
    (1, "Alice", "Dept_A"),
    (2, "Bob", "Dept_B"),
    (3, "Charlie", "Dept_C"),
    (4, "David", "Dept_X")
]
employees_df = spark.createDataFrame(employees_data, ["emp_id", "name", "dept_id"])

# Right: Departments
departments_data = [
    ("Dept_A", "Engineering"),
    ("Dept_B", "Marketing"),
    ("Dept_C", "Sales"),
    ("Dept_D", "Finance")
]
departments_df = spark.createDataFrame(departments_data, ["dept_id", "dept_name"])

# 3. Inner Join (David is excluded; Dept D is excluded)
inner_df = employees_df.join(departments_df, "dept_id", "inner")
inner_df.show()

# 4. Left Outer Join (David is included with dept name as null)
left_df = employees_df.join(departments_df, "dept_id", "left")
left_df.show()

# 5. Left Semi Join (Filters employees who belong to a valid department)
semi_df = employees_df.join(departments_df, "dept_id", "left_semi")
semi_df.show()

# 6. Left Anti Join (Finds employees belonging to invalid/missing departments)
anti_df = employees_df.join(departments_df, "dept_id", "left_anti")
anti_df.show()
Find this content helpful? ☕ Buy me a coffee

Entity Details

Create New Item

celebration
Enjoying the free content?

Create a free account to track your progress and save your place.

Create Free Account
help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.